package main;

import GUI.*;
import connection.VLCv2;
import connection.VLCv2.PlayState;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Timer;

/**
 * ****************************************************************************
 * @author Tjarco Project expo Team75
 *
 * De main klasse. Vanaf hier wordt de MME gecontroleerd en worden de
 * verschillende schermen geopend.
 * 
 * Dit werk is gelicenseerd onder een Creative Commons Naamsvermelding-NietCommercieel-GeenAfgeleideWerken 3.0 Unported licentie.
 * Ga naar http://creativecommons.org/licenses/by-nc-nd/3.0/ om een kopie van de licentie te kunnen lezen.
 * 
 * ****************************************************************************
 */
public class Main {
    //De variabelen voor de connectie
    private final String IP = "145.92.74.49";
    private final String FILMPJE = "C:\\filmpjes\\full.mov";
    private final String SCENE1 = "C:\\filmpjes\\scene1.mov";
    private final String SCENE2 = "C:\\filmpjes\\scene2.mov";
    private final String SCENE3 = "C:\\filmpjes\\scene3.mov";
    private final String SCENE4 = "C:\\filmpjes\\scene4.mov";
    private final String INACTIEF = "C:\\filmpjes\\idle.mp4";
    private final String GAME="C:\\filmpjes\\game.mp4";
    private final String EIND="C:\\filmpjes\\eind.mp4";
    private String huidigFilmpje;
    private boolean restart;
    
    public enum Scherm {

        MAIN,
        FILM,
        NAFILM,
        GAME,
        NAGAME,
        EIND
    }
    
    Scherm huidigScherm;
    
    
    //De GUI's:
    gui_main GMain;
    gui_filmpje GFilmpje;
    gui_naFilmpje GNaFilmpje;
    gui_naGame GNaGame;
    gui_einde GEinde;
    
    //Waarde voor muisbeweging check
    Boolean mouseTimerBestaat = false;
    Point mousePosition;
    Timer mouseMonitor;
    int mouseNotMovedTime;
    
    //graphic boolean
    private boolean GraphicActive;

    //De game:
    Memory_spel_run spel;
    //Booleans voor controleren van de uitvoer van het programma
    //      -Zolang het programRun true is, worden in de main-methode de methoden de methoden 
    //        Uitgevoerd voor het controleren van de knoppen en de playState van de filmpjes
    //      -Als canCheckPlaySate true is wordt er gekeken wat de playstate van het filmpje is
    boolean programRun = true;
    boolean canCheckPlayState = false;
    //Met vlc wordt de verbinding met de vlc speler geregeld, en kunnen er filmpjes worden afgespeeld
    //Met de PlayState kan de status  van het filmpje verkregen worden. (afspelend, gepauzerd of gestopt)
    VLCv2 vlc;
    private PlayState state;
    private boolean loop;
    
    int mouseX;
    int mouseY;

    public Main() {
        //Maak de GUI's aan, zet Main op vissible
        GMain = new gui_main();
        GFilmpje = new gui_filmpje();
        GNaFilmpje = new gui_naFilmpje();
        GNaGame = new gui_naGame();
        GEinde = new gui_einde();
        GMain.setVisible(true);
        restart = false;
        

        //Kijk waar de muis zich op het begin bevind
        // 1. voor de graphic
        mouseX=MouseInfo.getPointerInfo().getLocation().x;
        mouseY=MouseInfo.getPointerInfo().getLocation().y;
        // 2. voor de listener
        mousePosition = MouseInfo.getPointerInfo().getLocation();

        //graphic moet active zijn op het begin
        this.GraphicActive=true;
        
        //Maak connectie met de vlc player
        vlc = new VLCv2(IP, 1234);

        try {
            vlc.connect();
        } catch (Exception e) {
            //do nothing
        }
        
        loop = false;
        
        //Maak het spel aan
        spel = new Memory_spel_run();

    }
    private void SwitchScherm( Scherm nieuwScherm )
    {
        
        if( huidigScherm == nieuwScherm ){
            return;
        }
        
        if( GMain.isVisible() && nieuwScherm != Scherm.MAIN)
            GMain.setVisible( false );
        else if( !GMain.isVisible() && nieuwScherm == Scherm.MAIN )
            GMain.setVisible( true );
        
        if( GFilmpje.isVisible() && nieuwScherm != Scherm.FILM)
            GFilmpje.setVisible( false );
        else if( !GFilmpje.isVisible() && nieuwScherm == Scherm.FILM ){
            GFilmpje.setVisible( true );
                   }
        
        if( GNaFilmpje.isVisible() && nieuwScherm != Scherm.NAFILM)
            GNaFilmpje.setVisible( false );
        else if( !GNaFilmpje.isVisible() && nieuwScherm == Scherm.NAFILM )
            GNaFilmpje.setVisible( true );
        
        if(spel!=null){
        if( spel.isProgramRun() && nieuwScherm != Scherm.GAME)
            spel.stopGame();
        else if( spel.isProgramRun() && nieuwScherm == Scherm.GAME )
            spel.run(this);
        }
        
        if( GNaGame.isVisible() && nieuwScherm != Scherm.NAGAME)
            GNaGame.setVisible( false );
        else if( !GNaGame.isVisible() && nieuwScherm == Scherm.NAGAME )
            GNaGame.setVisible( true );
        
        if( GEinde.isVisible() && nieuwScherm != Scherm.EIND)
            GEinde.setVisible( false );
        else if( !GEinde.isVisible() && nieuwScherm == Scherm.EIND )
            GEinde.setVisible( true );
        
        try {
            Thread.sleep(150);
        } catch (InterruptedException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        //Stel wachttijd in.
        //Normaal is 100ms de delay waarbij de beweging timeout 20 seconden is (200*100).
        //Bij de game is dit 500ms wat de beweging timeout 100 seconden maakt (200*500).
        if(mouseMonitor!=null){
        if( nieuwScherm == Scherm.GAME )
            mouseMonitor.setDelay( 500 );
        else
            mouseMonitor.setDelay( 100 );
        }
        
        if(mouseMonitor!=null){
        if(nieuwScherm == Scherm.FILM )
            stopMuisTimer();
        else
            startMuisTimer();
        }
        huidigScherm = nieuwScherm;
        
    }
    
    /*
     * 
     * Muis timer
     * Houd de muisbewegingen in de gaten en gaat naar main indien nodig.
     * 
     */
    
    private void maakMuisTimer()
    {
        if( !mouseTimerBestaat )
        {   
            mouseMonitorListener lis = new mouseMonitorListener();
            mouseMonitor = new Timer( 100, lis );
            mouseMonitor.setInitialDelay(100);
            mouseMonitor.start();
            mouseMonitor.stop();
            mouseTimerBestaat = true;
            
        }
    }
    private void startMuisTimer()
    {
        if(mouseMonitor!=null){
        mouseNotMovedTime = 0;
        mouseMonitor.restart();
        }
    }
    private void stopMuisTimer()
    {
        if(mouseMonitor!=null){
        
        mouseNotMovedTime = 0;
        mouseMonitor.stop();
        }
    }
    
   
    private class mouseMonitorListener implements ActionListener{
    //Dit event vangt de timer op en voert de acties uit.
    @Override
    public void actionPerformed(ActionEvent evt) {
         Point newMousePosition = MouseInfo.getPointerInfo().getLocation();
        int mouseXDifference = Math.abs( newMousePosition.x - mousePosition.x );
        int mouseYDifference = Math.abs( newMousePosition.y - mousePosition.y );
        int mouseTopDifference = Math.max( mouseXDifference, mouseYDifference );
        
        if( mouseTopDifference < 5 )
            mouseNotMovedTime += 1;
        else
        {
            mousePosition = MouseInfo.getPointerInfo().getLocation();
            mouseNotMovedTime = 0;
        }
        
        if( mouseNotMovedTime < 200 ) //Als de muis minder dan 20 seconden ( 200 * 100ms ) geleden begonnen is....
            return;//Annuleer deze ronde en wacht op de volgende...
        
        //Als de muis meer dan 20 seconden geleden bewogen is...
       mouseMonitor.stop(); //Stop de timer.
       restart = true;
     
    }
    }

    //De code om te kijken of er op knoppen is gedrukt
// <editor-fold defaultstate="collapsed" desc=" gui_main knoppen ">
    public void checkMainButtonsPressed() {


        if (GMain.isButtonFilmpjePressed()) {
            GMain.setVisible(false);
            GMain.setButtonFilmpjePressed(false);
            GFilmpje.setVisible(true);
            startFilmpje(FILMPJE,false);
            SwitchScherm(Scherm.FILM);
            
        } else if (GMain.isButtonGamePressed()) {
            GMain.setButtonGamePressed(false);
            GMain.setVisible(false);
            startFilmpje(GAME, true);
            spel = new Memory_spel_run();
            spel.run(this);
            SwitchScherm(Scherm.GAME);
        }
        

    }

// </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" gui_filmpje knoppen ">
    public void checkFilmpjeButtonsPressed() {
        if (GFilmpje.isButtonBackPressed()) {
            GMain.setVisible(true);
            GFilmpje.setVisible(false);
            GFilmpje.setButtonBackPressed(false);
            vlc.rc.clear();
            this.canCheckPlayState=false;
            SwitchScherm(Scherm.MAIN);
        } else if (GFilmpje.isButtonScene1Pressed()) {
            startFilmpje(SCENE1,false);
            GFilmpje.setButtonScene1Pressed(false);
        } else if (GFilmpje.isButtonScene2Pressed()) {
            startFilmpje(SCENE2,false);
            GFilmpje.setButtonScene2Pressed(false);
        } else if (GFilmpje.isButtonScene3Pressed()) {
            startFilmpje(SCENE3,false);
            GFilmpje.setButtonScene3Pressed(false);
        } else if (GFilmpje.isButtonScene4Pressed()) {
            startFilmpje(SCENE4,false);
            GFilmpje.setButtonScene4Pressed(false);
        }
    }

// </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" gui_naFilmpje knoppen ">
    public void checkNaFilmButtonsPressed() {

        if (GNaFilmpje.isButtonBackPressed()) {
            this.GNaFilmpje.setVisible(false);
            this.GFilmpje.setVisible(true);
            GNaFilmpje.setButtonBackPressed(false);
            startFilmpje(this.FILMPJE,false);
            SwitchScherm(Scherm.FILM);
        } else if (GNaFilmpje.isButtonBeëindigPressed()) {
            GNaFilmpje.setButtonBeëndigPressed(false);
            GNaFilmpje.setVisible(false);
            GEinde.setVisible(true);
            this.startFilmpje(EIND, true);
            SwitchScherm(Scherm.EIND);
        } else if (GNaFilmpje.isButtonGamePressed()) {
            GNaFilmpje.setButtonGamePressed(false);
            GNaFilmpje.setButtonBackPressed(false);
            this.startFilmpje(GAME, true);
            spel = new Memory_spel_run();
            spel.run(this);
            SwitchScherm(Scherm.GAME);
        }
    }

// </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" gui_naGame knoppen ">
    public void checkNaGameButtonsPressed() {
        if (GNaGame.isButtonBackPressed()) {
            GNaGame.setVisible(false);
            spel = new Memory_spel_run();
            SwitchScherm(Scherm.GAME);
            this.startFilmpje(GAME, true);
            GNaGame.setButtonBackPressed(false);
        } else if (GNaGame.isButtonFilmpjePressed()) {
            GNaGame.setVisible(false);
            GNaGame.setButtonFilmpjePressed(false);
            GFilmpje.setVisible(true);
            startFilmpje(FILMPJE,false);
            SwitchScherm(Scherm.FILM);
        } else if (GNaGame.isButtonBeëindigPressed()) {
            GNaGame.setButtonBeëindigPressed(false);
            GNaGame.setVisible(false);
            GEinde.setVisible(true);
            startFilmpje(EIND,true);
            SwitchScherm(Scherm.EIND);
            
        }


    }

// </editor-fold>
    
// <editor-fold defaultstate="collapsed" desc=" Code om een filmpje te starten ">
    public void startFilmpje(String url, boolean loop) {
        vlc.rc.clear();
        vlc.rc.enqueue(url);
        vlc.rc.play();
        vlc.rc.setLoop( loop );
        vlc.rc.fullscreen();
        
        this.huidigFilmpje=url;
        this.loop = loop;
        
//        try {
//            Thread.sleep(20);
//        } catch (InterruptedException ex) {
//            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        
        this.canCheckPlayState = true;
        
    }

    //Kijkt wat de playState van vlc is. als het filmpje is afgelopen naar de volgende status van
    //de MME gaan.
    public void checkPlayState() {
//        if(loop){
////            vlc.command("pause");
//            
//            int length = vlc.info.getLength();
//            if(vlc.info.getTime()>(length-1)){
//                this.startFilmpje(this.huidigFilmpje, true);
//            }
//        }
//        else{
        if (vlc.info.getTime() >= (vlc.info.getLength() - 0.1) && !this.loop) {
            vlc.rc.clear();
            this.GNaFilmpje.setVisible(true);
            this.GFilmpje.setVisible(false);
            SwitchScherm(Scherm.NAFILM);
            this.canCheckPlayState = false;
            this.startFilmpje(INACTIEF, true);
        }
//        }
    }

// </editor-fold>
    
// <editor-fold defaultstate="collapsed" desc=" Graphic ">
    public void beginGraphic() {


        //get the standard x
        int x = GMain.labelWiiRemote.getX();


        // 1) label omhoog zetten 2) label omlaag zetten
        while (this.GraphicActive) {
            for (int i = 110; i > 0; i--) {
                try {
                    if (this.GraphicActive) {
                        GMain.labelWiiRemote.setLocation(x, i);
                        this.mouseMove();
                        Thread.sleep(10);
                    }
                } catch (InterruptedException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
                
            }
            for (int i = 0; i < 110; i++) {
                if (this.GraphicActive) {
                    GMain.labelWiiRemote.setLocation(x, i);
                    this.mouseMove();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }            
        }
        
    }
    
    public void mouseMove() {
       
        int verschilY = MouseInfo.getPointerInfo().getLocation().y - this.mouseY;
        
        GMain.pannelGraphic.setLocation( 0, Math.min( GMain.pannelGraphic.getLocation().y + verschilY, 0 ) );
        GMain.pannelGraphic.revalidate();
        
        this.mouseX = MouseInfo.getPointerInfo().getLocation().x;
        this.mouseY = MouseInfo.getPointerInfo().getLocation().y;
        
        if (GMain.pannelGraphic.getLocation().y < -350) {
            for (int i = -350; i > -1000; i -= 5) {
                GMain.pannelGraphic.setLocation(GMain.pannelGraphic.getLocation().x, i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
            GMain.pannelGraphic.setVisible(false);
            this.GraphicActive = false;            
            startMuisTimer();
        }
    }

// </editor-fold>
    

    public static void main(String[] args) {
        Main m = new Main();
        m.startFilmpje(m.INACTIEF, true);
        m.maakMuisTimer();
        
        //De begingraphic uitvoeren
        m.beginGraphic();
       
        
        
      

        while (m.programRun) {
            
                if (m.canCheckPlayState) {
                    m.checkPlayState();
                try {
                    Thread.sleep(5);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
                }

// <editor-fold defaultstate="collapsed" desc="gui_main knop methoden ">
            if (m.GMain.isVisible()) {
                m.checkMainButtonsPressed();

                
            try {
                Thread.sleep(5);
            } catch (InterruptedException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }

            } // </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" gui_filmpje knop methoden ">
            else if (m.GFilmpje.isVisible()) {
                m.checkFilmpjeButtonsPressed();

               
            try {
                Thread.sleep(5);
            } catch (InterruptedException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } 
            } // </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" gui_naFilmpje knop methoden ">
            else if (m.GNaFilmpje.isVisible()) {
                m.checkNaFilmButtonsPressed();
                
                
            try {
                Thread.sleep(5);
            } catch (InterruptedException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
            }

// </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" gui_naGame knoppen ">
            if (m.GNaGame.isVisible()) {
                m.checkNaGameButtonsPressed();
            }

// </editor-fold>
            
            if(m.spel!=null){
            if(!m.spel.isProgramRun()&&m.huidigScherm==Scherm.GAME){
               if(m.spel.isMainNext()){
               m.SwitchScherm(Scherm.MAIN);
               m.spel=null;
               m.startFilmpje(m.INACTIEF, true);
               }else{
               m.SwitchScherm(Scherm.NAGAME);
               m.spel=null;
               m.startFilmpje(m.INACTIEF, true);
               }
               
            }
            }
            
            if(m.restart){
                m.vlc.disconnect();
                m.vlc.interrupt();
                m.vlc = null;
                m.GEinde.setEnabled(false);
                m.GNaFilmpje.setEnabled(false);
                m.GNaGame.setEnabled(false);
            try {
                m.finalize();
            } catch (Throwable ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
                m=null;
            
            Main.main(args);
        }



    }

    }
       
}